package com.example.dl645.service;

import com.example.dl645.model.MeterData;
import com.example.dl645.protocol.dl645.Dl645Frame;
import io.netty.channel.Channel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 电表数据读取服务
 */
@Service
public class MeterReaderService {

    @Autowired
    private ConcentratorConnectionManager connectionManager;

    private final Map<String, byte[]> responseCache = new ConcurrentHashMap<>();
    private final Lock lock = new ReentrantLock();
    private final Condition responseCondition = lock.newCondition();

    /**
     * 查询正向有功电能
     */
    public MeterData queryActiveEnergy(String concentratorId, String meterHexAddress) throws Exception {
        // 参数校验
        if (concentratorId == null || meterHexAddress == null || meterHexAddress.length() != 12) {
            throw new IllegalArgumentException("集中器ID或电表地址格式错误");
        }

        // 获取连接
        Channel channel = connectionManager.getChannel(concentratorId);
        if (channel == null || !channel.isActive()) {
            throw new RuntimeException("集中器[" + concentratorId + "]未连接");
        }

        // 构建查询帧（DL/T 645协议）
        byte[] meterAddress = hexToBytes(meterHexAddress);
        Dl645Frame frame = new Dl645Frame(meterAddress, (byte) 0x48, new byte[]{(byte) 0xB4, (byte) 0x0C, (byte) 0x60, (byte) 0x00}); // 通用查询帧
        byte[] commandFrame = frame.toBytes();

        // 发送指令并等待响应
        responseCache.remove(concentratorId);
        channel.writeAndFlush(commandFrame).sync();
        System.out.println("📤 向集中器[" + concentratorId + "]发送查询指令，电表地址：" + meterHexAddress);

        // 等待响应（超时5秒）
        lock.lock();
        try {
            boolean received = responseCondition.await(5, TimeUnit.SECONDS);
            if (!received || responseCache.get(concentratorId) == null) {
                throw new RuntimeException("等待响应超时（5秒）");
            }
        } finally {
            lock.unlock();
        }
        return null;
    }

    private byte[] hexToBytes(String hex) {
        int len = hex.length();
        byte[] data = new byte[len / 2];
        for (int i = 0; i < len; i += 2) {
            data[i / 2] = (byte) ((Character.digit(hex.charAt(i), 16) << 4) + Character.digit(hex.charAt(i + 1), 16));
        }
        return data;
    }
}